/*****************************************************************************
 * file  : systask.c
 * creat : apleilx
 * data  : 2017/11/05
 *******************************************************************************/
#include "os_obj.h"
#include "sys_task.h"
#include "pincfg.h"
#include "framework.h"
#include "rc522/src/rfid_utils.h"

/*****************************************************************************
 * @brief   fun.
 *****************************************************************************/
uint8_t ext_spi_rw(uint8_t dataw);
void userTapIn(void);

/*****************************************************************************
 * @brief   var.
 *****************************************************************************/
 
/*******************************************************************************
 * @brief: init
 * @param argc 参数数量
 * @param argv 参数指针
 * @return 错误代码
 ******************************************************************************/
void rc522_spi_read(uu08 *buff, uu08 addr, uu08 len, uu08 addr_inc)
{
	int index;
	
	rfid_cs.dis();
	
	ext_spi_rw(_BIT(7)| (addr<<1));
	
	for(index=0; index < len; index++)
	{
		addr += addr_inc;
		buff[index] = ext_spi_rw(_BIT(7)| (addr<<1));
	}
	
	buff[index] = ext_spi_rw(0);
	
	rfid_cs.en();
}

void rc522_spi_write(uu08 *buff, uu08 addr, uu08 len)
{
	int index;
	
	rfid_cs.dis();
	
	ext_spi_rw(addr << 1);
	
	for(index=0; index < len; index++)
	{
		ext_spi_rw(buff[index]);
	}
	
	rfid_cs.en();
}

/*******************************************************************************
 * @brief: init
 * @param argc 参数数量
 * @param argv 参数指针
 * @return 错误代码
 ******************************************************************************/
int rc522_init(int argc, char *argv[])
{
	uu08 buff[80];
	int index;
	
	rfid_cs.dir_out_pp();
	rfid_rst.dir_out_pp();
	
	rfid_cs.en();
	rfid_rst.dis();
	osDelay(ms_ticks(100));
	rfid_rst.en();
	osDelay(ms_ticks(200));
	
	dbg_puts("init end! \n");
	
	return 0;
}
DBG_FUN_EXPORT(rc522_init);

int rc522_reg_read(int argc, char *argv[])
{
	uu08 buff[80];
	int index;
	uu08 addr = 0;
	uu08 len = 1;
	uu08 addr_inc = 0;
	
	if(argc > 1)
		addr = atoi(argv[1]);
	
	if(argc > 2)
		len = atoi(argv[2]);
	
	if(argc > 3)
		addr_inc = atoi(argv[3]);
	
	rc522_spi_read(buff, addr, len, addr_inc);
	
	dbg_u8_print("rc522 reg read:\n", buff, len, 16);
	
	dbg_puts(SYMBOL_LINE_DOT PTCR);
	return 0;
}
DBG_FUN_EXPORT(rc522_reg_read);

int rc522_reg_write(int argc, char *argv[])
{
	uu08 buff[80];
	int index;
	uu08 addr = 0;
	uu08 len = 0;
	
	if(argc < 3)
		return 1;
	
	addr = atoi(argv[1]);
	len = ascii_to_hex2_multi(argv[2], buff, 80);
	
	rc522_spi_write(buff, addr, len);
	
	dbg_u8_print("rc522 reg write:\n", buff, len, 16);
	
	dbg_puts(SYMBOL_LINE_DOT PTCR);
	return 0;
}
DBG_FUN_EXPORT(rc522_reg_write);


void MFRC522_SS_enable(void)
{
	rfid_cs.dis();
}

void MFRC522_SS_disable(void)
{
	rfid_cs.en();
}

void MFRC522_RST_enable(void)
{
	rfid_rst.dis();
}

void MFRC522_RST_disable(void)
{
	rfid_rst.en();
}

const struct MFRC522_HAL_T rc522_hal = {
	MFRC522_SS_enable,
	MFRC522_SS_disable,
	MFRC522_RST_enable,
	MFRC522_RST_disable,
	ext_spi_rw
};

struct MFRC522_T mfrcInstance;
int last_balance = 0;
unsigned int last_user_ID;
uu08 rc522_scan_en = 0;
#define MIN_BALANCE 300

int rc522_lib_init(int argc, char *argv[])
{
	uu08 buff[80];
	
	rfid_cs.dir_out_pp();
	rfid_rst.dir_out_pp();
	
	mfrcInstance.hal = &rc522_hal;
	
	setupRFID(&mfrcInstance);
	
	rc522_scan_en = 1;
	
	dbg_puts(SYMBOL_LINE_DOT PTCR);
	return 0;
}
DBG_FUN_EXPORT(rc522_lib_init);


void MFRC522_scan(void)
{
	if(rc522_scan_en)
	{
		// Look for new cards in RFID2
		if (PICC_IsNewCardPresent(&mfrcInstance)) {
			// Select one of the cards
			if (PICC_ReadCardSerial(&mfrcInstance)) {
//				int status = writeCardBalance(mfrcInstance, 100000); // used to recharge the card
				 userTapIn();
			}
		}
	}
}
obj_app_order(MFRC522_scan);


/*******************************************************************************
 *  System routine functions
 ******************************************************************************/

/**
 * Executed every time the card reader detects a user in
 */
void userTapIn(void) {

//	show card UID
	dbg_print("\nCard uid bytes: ");
	for (uint8_t i = 0; i < mfrcInstance.uid.size; i++) {
		dbg_print(" %X", mfrcInstance.uid.uidByte[i]);
	}
	dbg_print("\n\r");


	// Convert the uid bytes to an integer, byte[0] is the MSB
	last_user_ID =
		(int)mfrcInstance.uid.uidByte[3] |
		(int)mfrcInstance.uid.uidByte[2] << 8 |
		(int)mfrcInstance.uid.uidByte[1] << 16 |
		(int)mfrcInstance.uid.uidByte[0] << 24;

	dbg_print("\nCard Read user ID: %u ",last_user_ID);


		// Read the user balance
		last_balance = readCardBalance(&mfrcInstance);

		if (last_balance == (-999)) {
			// Error handling, the card does not have proper balance data inside
		} else {
			// Check for minimum balance
			if (last_balance < MIN_BALANCE) {
				dbg_print(", Insufficient balance\n");
			} else {
				dbg_print(", Balance OK\n");
			}
		}
}

extern uint8_t auxBuffer[];
int rc522_lib_read(int argc, char *argv[])
{
	int block = 0;
	
	if(argc > 1)
		block = atoi(argv[1]);
	
	rang_limit(block, 0, 63);
	
	readCardBlock(&mfrcInstance, 0, block);
	
	dbg_u8_print("ic card dat:" PTCR, auxBuffer, 16, 16);
	
	dbg_puts(SYMBOL_LINE_DOT PTCR);
	return 0;
}
DBG_FUN_EXPORT(rc522_lib_read);
